package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.attendance.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.system.dto.SysRoleDTO;
import com.nineclock.system.entity.ExcelMember;
import com.nineclock.system.entity.ExcelMemberListener;

import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.system.dto.SysCompanyUserDTO;

import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
@Slf4j
public class SysCompanyUserServiceImpl implements SysCompanyUserService {

    @Autowired
    SysCompanyUserMapper companyUserMapper;
    @Autowired
    SysDepartmentMapper departmentMapper;

    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    SysRoleMapper roleMapper;


    @Override
    public List<SysCompanyUserDTO> queryCompanyMemberList() {
        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //查询当前企业的员工列表
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);

        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);
        //如果不为null， 转换为dto 并返回
        if(CollectionUtil.isNotEmpty(companyUserList)){
            List<SysCompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
            return companyUserDTOList;
        }

        return null;
    }
    /**
     *  @Date: 2021/6/17 11:32
     *  员工查询:
     *  点击左侧树形部门节点，查询当前部门下包括子部门包含的员工记录，并支持分页和条件查询 。
     * - 请求方式：GET
     * - 请求路径：/organization/members
     * - 请求参数：
     *   page  当前页码
     *   pageSize 页大小
     *   departmentId 部门ID 如果为空或为0，则为查询企业所有员工
     *   keyword 关键字，模糊匹配员工名称、工号、手机号等
     * - 返回结果：返回用户分页数据，用户记录中包含部门信息
     */
    @Override
    public PageResult<SysCompanyUserDTO> members(Integer page, Integer pageSize, String keyword, Long departmentId) {

        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        //keyword  关键词  模糊查询
        if(keyword != null){
            wrapper.and(wrapper1->{
                wrapper1.like(SysCompanyUser::getUserName, keyword)
                        .or().like(SysCompanyUser::getWorkNumber, keyword)
                        .or().like(SysCompanyUser::getMobile, keyword);
            });
        }

        //departmentId = 10009 查询该部门的员工信息,  查询该部门的子部门id集合
        List<Long> ids = new ArrayList<>();
        if(departmentId != 0){
            ids.add(departmentId);
        }
        //查询子部门id
        this.queryChildDepartmentIds(ids , departmentId);
        wrapper.in(SysCompanyUser::getDepartmentId, ids);


        //创建Page对象
        Page<SysCompanyUser> companyUserPage = new Page<>(page, pageSize);

        //分页查询
        companyUserPage = companyUserMapper.selectPage(companyUserPage, wrapper);
        //获取数据列表
        List<SysCompanyUser> records = companyUserPage.getRecords();
        return new PageResult(
                companyUserPage.getTotal(),
                companyUserPage.getPages(),
                BeanHelper.copyWithCollection(records, SysCompanyUserDTO.class));
    }



    @Override
    public void importData(MultipartFile excelFile) throws IOException {

        EasyExcel.read(excelFile.getInputStream(), ExcelMember.class, new ExcelMemberListener(this))
                 .sheet(0) //读取第 0个工作表
                 .doRead(); //执行 读 操作
    }

    @Autowired
    SysUserMapper userMapper;

    @Override
    public void handleParsedData(List<ExcelMember> list) {
        if(CollectionUtil.isNotEmpty(list)){
            for (ExcelMember excelMember : list) {
                //判断手机号和邮箱是否 唯一
                LambdaQueryWrapper<SysUser> userQw = new LambdaQueryWrapper<>();
                userQw.eq(SysUser::getMobile, excelMember.getMobile())
                      .or().eq(SysUser::getEmail, excelMember.getEmail());

                Integer count = userMapper.selectCount(userQw);
                if(count > 0){
                    throw new NcException(ResponseEnum.USER_MOBILE_EMAIL_EXISTS);
                }
                //判断工号 是否唯一
                LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
                companyUserQw.eq(SysCompanyUser::getWorkNumber, excelMember.getWorkNumber() );
                companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());

                Integer count1 = companyUserMapper.selectCount(companyUserQw);
                if(count1 > 0) {
                    throw new NcException(ResponseEnum.WROK_NUM_EXISTS);
                }

                //保存用户信息
                SysUser user = new SysUser();
                user.setUsername(excelMember.getName());
                user.setMobile(excelMember.getMobile());
                user.setEmail(excelMember.getEmail());
                user.setPassword(new BCryptPasswordEncoder().encode("123456"));
                user.setStatus((short)1);
                user.setCreateTime(new Date());
                user.setLastLoginCompanyId(CurrentUserHolder.get().getCompanyId());

                userMapper.insert(user);

                //保存员工信息
                SysCompanyUser companyUser = new SysCompanyUser();
                companyUser.setUserId(user.getId());
                companyUser.setUserName(excelMember.getName());
                companyUser.setMobile(excelMember.getMobile());

                //设置部门信息: 先查， 再存
                if(StrUtil.isNotEmpty(excelMember.getDepartmentName())){
                    //根据部门名称， 先查询对应的部门信息
                    LambdaQueryWrapper<SysDepartment> departmentQw = new LambdaQueryWrapper<>();
                    departmentQw.eq(SysDepartment::getName, excelMember.getDepartmentName());
                    departmentQw.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());

                    SysDepartment department = departmentMapper.selectOne(departmentQw);
                    if(department != null){
                        companyUser.setDepartmentId(department.getId());
                        companyUser.setDepartmentName(department.getName());
                    }
                }

                companyUser.setPost(excelMember.getPosition());
                companyUser.setWorkNumber(excelMember.getWorkNumber());
                companyUser.setEmail(excelMember.getEmail());
                companyUser.setOfficeAddress(excelMember.getWorkAddr());
                companyUser.setRemark(excelMember.getDesc());
                companyUser.setTimeEntry(excelMember.getEntryTime());
                companyUser.setEnable((short) ("可用".equals(excelMember.getEnable()) ? 1: 0));

                //新增员工
                companyUserMapper.insert(companyUser);

                //维护用户和角色的中间表
                //根据角色名称，查询角色对象
                LambdaQueryWrapper<SysRole> roleQw = new LambdaQueryWrapper<>();
                roleQw.eq(SysRole::getCompanyId, CurrentUserHolder.get().getCompanyId());
                roleQw.eq(SysRole::getRoleDesc, excelMember.getRoleName());

                SysRole role = roleMapper.selectOne(roleQw);
                if(role != null){
                    SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
                    companyUserRole.setCompanyUserId(companyUser.getId());
                    companyUserRole.setCompanyId(CurrentUserHolder.get().getCompanyId());
                    companyUserRole.setRoleId(role.getId());
                    //保存员工和角色的关系
                    companyUserRoleMapper.insert(companyUserRole);
                }

            }
        }

    }


    /**
     *  @Date: 2021/6/17 18:54
     *  根据部门ID, 查询该部门下的员工数量
     */
    @Override
    public Integer queryUserCountByDepartmentIds(List<Long> departmentIds) {

        List<Long> ids = new ArrayList<>();
        ids.addAll(departmentIds);
        //查询这些部门 的子部门信息
        if(departmentIds != null){
            for (Long departmentId : departmentIds) {
                this.queryChildDepartmentIds(ids, departmentId);
            }
        }

        //统计员工的数量
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(SysCompanyUser::getCompanyId,CurrentUserHolder.get().getCompanyId());
        //判断 员工所在部门是否在集合中
        wrapper.in(SysCompanyUser::getDepartmentId, ids);

        Integer count = companyUserMapper.selectCount(wrapper);
        return count;
    }

    /**
     * 查询 指定部门的 下级部门及员工信息
     * @param departmentId
     * @param includeMember
     * @return
     */
    @Override
    public List<DepartmentOrUserSimpleDTO> querySimpleDepartment(Long departmentId, Integer includeMember) {

        List<DepartmentOrUserSimpleDTO> departmentOrUserSimpleDTOList = new ArrayList<>();

        //健壮性的判断
        if(departmentId == null || includeMember == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //先查询 下级部门信息
        LambdaQueryWrapper<SysDepartment> departmentQw = new LambdaQueryWrapper<>();
        departmentQw.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        departmentQw.eq(SysDepartment::getParentId, departmentId);
        //查询获取 下级部门列表
        List<SysDepartment> departmentList = departmentMapper.selectList(departmentQw);
        if(CollectionUtil.isNotEmpty(departmentList)){
            for (SysDepartment department : departmentList) {
                //转换为 simple 对象
                DepartmentOrUserSimpleDTO departmentSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentSimpleDTO.setId(department.getId());
                departmentSimpleDTO.setName(department.getName());
                departmentSimpleDTO.setType(1); //类型为部门

                departmentOrUserSimpleDTOList.add(departmentSimpleDTO);
            }
        }


        //includeMember = 0 说明包含员工信息， 查询员工列表
        if(includeMember == 0){
            LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();
            companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
            companyUserQw.eq(SysCompanyUser::getDepartmentId, departmentId);
            //获取该部门的员工信息
            List<SysCompanyUser> companyUserList = companyUserMapper.selectList(companyUserQw);
            if(CollectionUtil.isNotEmpty(companyUserList)){
                for (SysCompanyUser companyUser : companyUserList) {
                    DepartmentOrUserSimpleDTO userSimpleDTO = new DepartmentOrUserSimpleDTO();
                    userSimpleDTO.setId(companyUser.getId());
                    userSimpleDTO.setName(companyUser.getUserName());
                    userSimpleDTO.setType(2);

                    //添加到集合中
                    departmentOrUserSimpleDTOList.add(userSimpleDTO);
                }
            }
        }

        return departmentOrUserSimpleDTOList;
    }


    private void queryChildDepartmentIds(List<Long> ids, Long departmentId) {
        LambdaQueryWrapper<SysDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDepartment::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(SysDepartment::getParentId, departmentId);
        //子部门列表
        List<SysDepartment> departmentList = departmentMapper.selectList(wrapper);

        if(CollectionUtil.isNotEmpty(departmentList)){
            //把部门列表集合转换为 部门id集合
            List<Long> departmentIds = departmentList.stream().map(department -> {
                return department.getId();
            }).collect(Collectors.toList());
            //把部门id 添加到 集合中
            ids.addAll(departmentIds);

            //循环部门id， 再次查询子部门
            for (Long id : departmentIds) {
                this.queryChildDepartmentIds(ids, id);
            }
        }
    }
    @Override
    public SysCompanyUserDTO queryOne(String mobile) {
        if(mobile == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getMobile,mobile);
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());

        SysCompanyUser companyUser = companyUserMapper.selectOne(wrapper);
        if(companyUser != null){
            return BeanHelper.copyProperties(companyUser, SysCompanyUserDTO.class);
        }

        return null;
    }
    @Autowired
    SysCompanyMapper companyMapper;
    @Override
    public SysCompanyUserDTO queryAdminByCompanyId(Long companyId) {
        SysCompanyUser companyUser = companyMapper.getCurrentAdmin(companyId);

        if(companyUser != null){
            return BeanHelper.copyProperties(companyUser, SysCompanyUserDTO.class);
        }
        return null;
    }

    @Override
    public List<SysCompanyUserDTO> queryCompanyUser(Long userId, Long companyId) {
        //健壮性判断
        if(userId == null && companyId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //根据用户id和 企业id 查询员工信息
        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();

        if(userId != null){
            companyUserQw.eq(SysCompanyUser::getUserId, userId);
        }

        if(companyId != null){
            companyUserQw.eq(SysCompanyUser::getCompanyId, companyId);
        }
        //必须 已经审核加入 企业的员工
        companyUserQw.eq(SysCompanyUser::getEnable, 1);
        //获取 用户和企业对应的员工列表
        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(companyUserQw);

        if(CollectionUtil.isNotEmpty(companyUserList)){
            List<SysCompanyUserDTO> companyUserDTOList = BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
            //循环 员工列表， 查询每个员工对应的角色列表
            for (SysCompanyUserDTO companyUserDTO : companyUserDTOList) {
                List<SysRole> roleList = roleMapper.queryRoleListByCompanyUserId(companyUserDTO.getId(), companyUserDTO.getCompanyId());
                if(CollectionUtil.isNotEmpty(roleList)){
                    companyUserDTO.setRoles(BeanHelper.copyWithCollection(roleList, SysRoleDTO.class));
                }
            }

            return companyUserDTOList;
        }


        return null;
    }

    @Override
    public List<SysCompanyUserDTO> queryAllUserByCompanyId(Long companyId) {
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);

        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(companyUserList)){
            return BeanHelper.copyWithCollection(companyUserList, SysCompanyUserDTO.class);
        }
        return null;
    }

}
